package com.macro.mall.portal.controller;

import com.macro.mall.portal.util.SignUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;

@Log4j2
@Controller
@Api(tags = "WxMpController", description = "微信公众号")
@RequestMapping("/wx/mp")
public class WxMpController {
    @Value("${wx.mp.token}")
    private String TOKEN;
    @Autowired
    private WxMpService wxMpService;

    /**
     * @param signature 信服务端发来的加密签名
     * @param timestamp 时间戳
     * @param nonce     随机数
     * @param echostr   echostr
     * @param request
     * @param response
     * @throws IOException
     */
    @RequestMapping("/verify")
    @ApiOperation(value = "微信服务器资源验证")
    public void WXVerify(
            @RequestParam String signature,
            @RequestParam String timestamp,
            @RequestParam String nonce,
            @RequestParam String echostr,
            HttpServletRequest request,
            HttpServletResponse response
    ) throws IOException {
        log.info("signature:{},timestamp:{},nonce:{},echostr:{}", signature, timestamp, nonce, echostr);
        PrintWriter out = response.getWriter();
        // 请求校验，若校验成功则原样返回echostr，表示接入成功，否则接入失败
        if (SignUtil.checkSignature(TOKEN, signature, timestamp, nonce)) {
            out.print(echostr);
            log.info("成功");
        } else {
            log.info("验证失败！！！");
        }
        out.close();
    }

    @Value("${wx.mp.redirectURL}")
    private String url;

    @GetMapping("/authorize")
    @ApiOperation(value = "微信网页授权")
    public String authorize(@RequestParam("returnUrl") String returnUrl) {
        log.info("【微信网页授权】获取url,url={}", url);
//        1、以snsapi_base为scope发起的网页授权，是用来获取进入页面的用户的openid的，
//        并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页（往往是业务页面）

//        2、以snsapi_userinfo为scope发起的网页授权，是用来获取用户的基本信息的。
//        但这种授权需要用户手动同意，并且由于用户同意过，所以无须关注，就可在授权后获取该用户的基本信息。
        String redirectURL = wxMpService.oauth2buildAuthorizationUrl(url,
                WxConsts.OAuth2Scope.SNSAPI_BASE, URLEncoder.encode(returnUrl));

        log.info("【微信网页授权】获取code,redirectURL={}", redirectURL);
        return "redirect:" + redirectURL;
    }

    @GetMapping("/userInfo")
    @ApiOperation(value = "微信网页授权，获取oppid")
    public String userInfo(@RequestParam("code") String code,
                           @RequestParam("state") String returnUrl) throws Exception {
        log.info("【微信网页授权】 code={}", code);
        log.info("【微信网页授权】 state={}", returnUrl);
        WxMpOAuth2AccessToken wxMpOAuth2AccessToken;
        try {
            wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code);
        } catch (WxErrorException e) {
            log.info("【微信网页授权】{}", e);
            throw new Exception(e.getError().getErrorMsg());
        }
        String accessToken = wxMpOAuth2AccessToken.getAccessToken();
        log.info("【微信网页授权】 accessToken={}", accessToken);
        String openId = wxMpOAuth2AccessToken.getOpenId();
        log.info("【微信网页授权】 openId={}", openId);
        return "redirect:" + returnUrl + "?openid=" + openId;
    }
}
